<?php
declare(strict_types=1);
namespace Dao;
// hook dao_sys_user_use.php


use Field\SysUserColumns;
use Field\SysUserConst;
use Field\SysUserRow;
use Framework\Support\Request;
use Model\SysUserModel;
use Swoole\Timer;

class SysUserDao extends SysUserModel
{
	// hook dao_sys_user_public_start.php
    public $key_username = 'User:'.SysUserConst::UserName.':';
    public $key_data = 'User:Data:';

    public $key_up = 'User:Up:';
    public $key_down = 'User:Down:';
    /*
    public $key_mobile = 'user:mobile:';
    public $key_assets = 'user:assets:';
    public $key_user_id = 'user:user_id:';
    public $key_open_id = 'user:open_id:';
    public $key_open_uid = 'user:open_uid:';
    public $default_field = 'uid,user_id,parent_uid,level_id,username,nickname,avatar';
    */
	protected array $add_rule	=	[];
    protected array $edit_rule	=	[];


    protected array $rule	=	[
		/*
		"mobile"=>[
			"max"=>3
			"min"=>3
			"func"=>'isMobile'
			"error"=>false,
			'message'=>'格式有误'
		],
		"username"=>[
			"max"=>3
			"min"=>3
			"func"=>'checkS'
			"error"=>false,
			'message'=>'格式有误'
		],
		*/
	];
	//数据，字段，验证规则
	/*
	function isMobile($data,$field,$val){
	
		return true;
	}
	*/

	// hook dao_sys_user_public_end.php

    public function auto_load()
    {
        // hook model_user_auto_load_start.php
        //$this->add_with($this->UserAssets->table, 'uid', 'uid', '*');
        if ($this->http_server->worker_id == 0) {
            Timer::after(3000, function () {
                $this->reload();
            });
        }
    }

    public function reload($cond=[])
    {
        $user = $this->select($cond);
        if (!empty($user)) {
            foreach ($user as $v) {
                $this->T_SysUser->set($v['UserID'].'',$v);
                $this->T_SysUserMobile->set($v['Mobile'].'', ['UserID'=>$v[SysUserConst::UserID]]);
                $this->T_SysUserName->set($v['UserName'].'', ['UserID'=>$v[SysUserConst::UserID]]);
            }
            /*
            $data = [];
            $u = $user[0];
            for ($i = 0; $i < 200000; $i++) {
                $data['User:'.$i]=$u;
            }
            $this->CacheMSet($data);
            */
        }
    }


    public function read_by_UserID(int $UserID, $reload = 0):SysUserColumns
    {
        // hook model_user_read_by_uid_start.php
        $user =  $this->T_SysUser->get($UserID.'');
        if ($reload || empty($user[SysUserConst::UserID])) {
            $user = $this->read([SysUserConst::UserID=>$UserID]);
            // hook model_user_read_by_uid_user_cache_before.php
            $this->T_SysUser->set($UserID.'',$user);
            //$this->CacheSet($this->key_data . $uid, $user, 3600);
            // hook model_user_read_by_uid_user_cache_after.php
        }
        // hook model_user_read_by_uid_end.php
        return  (new SysUserRow($user))->data;
    }

    public function read_by_username(string $username):SysUserColumns
    {
        // hook model_user_read_by_username_start.php
        $user[SysUserConst::UserID] =  $this->T_SysUserName->get($username,'UserID');
        if (empty($user[SysUserConst::UserID])) {
            $user = $this->read([SysUserConst::UserName => $username],SysUserConst::UserID);
            if(!empty($user[SysUserConst::UserID])){
                $this->T_SysUserName->set($username, ['UserID'=>$user[SysUserConst::UserID]]);
            }
        }
        if (!empty($user[SysUserConst::UserID])) {
            $user = $this->read_by_UserID($user[SysUserConst::UserID]);
        } else {
            $user = new SysUserColumns();
        }
        // hook model_user_read_by_username_end.php
        return $user;
    }

    public function read_by_mobile(string $mobile):SysUserColumns
    {
        // hook model_user_read_by_mobile_start.php

        $user[SysUserConst::UserID] =   $this->T_SysUserMobile->get($mobile,'UserID');
        if (empty($user[SysUserConst::UserID])) {
            $user = $this->read([SysUserConst::Mobile => $mobile],SysUserConst::UserID);
            if(!empty($user[SysUserConst::UserID])){
                $this->T_SysUserMobile->set($mobile, ['UserID'=>$user[SysUserConst::UserID]]);
            }
        }
        if (!empty($user[SysUserConst::UserID])) {
            $user = $this->read_by_UserID($user[SysUserConst::UserID]);
        } else {
            $user = new SysUserColumns();
        }
        // hook model_user_read_by_mobile_end.php
        return $user;
    }

    public function make_token(Request $request,SysUserColumns $user)
    {
        if (empty($user->UserID) || $user->Status!=1) {
            $this->response('0003',[],'账户不存在或已锁定');
        }
        $ip =  $request->get_client_ip(1);
        $time = time()."";
        $this->updateByPk($user->UserID, [SysUserConst::LoginNum.'+' => 1]);

        // hook model_user_make_token_middle.php
        return xn_encrypt($time . "\t" . xn_encrypt((string)$time,'xkkXuhsMWwhWQLa0iTNJxSNDgscT4udS') . "\t" . xn_encrypt((string)$user->UserID, 'vqoz2Jdgp7wC0tCgu5WEM5Km6if8pi6T') . "\t" . substr($user->PassWord, 0, 16) . "\t" . $ip);
    }

    public function check_token(Request $request,string $token):SysUserColumns
    {
        if (empty($token)) {
            return new SysUserColumns();
        }
        $_token = xn_decrypt($token);
        $arr = explode("\t", $_token);
        if (!isset($arr[4])) {
            return new SysUserColumns();
        }

        $rand = xn_decrypt($arr[1], 'xkkXuhsMWwhWQLa0iTNJxSNDgscT4udS');
        $uid = xn_decrypt($arr[2], 'vqoz2Jdgp7wC0tCgu5WEM5Km6if8pi6T');
        if (empty($uid) || !is_numeric($uid) || !is_numeric($rand) || $rand!=$arr[0] ) {
            return new SysUserColumns();
        }
        $login_user = $this->read_by_UserID((int)$uid);
        if (empty($login_user->UserID)) {
            return new SysUserColumns();
        }
        return trim($arr[3]) != trim(substr($login_user->PassWord, 0, 16)) ? new SysUserColumns() : $login_user;
    }

    public function update(array $cond, array $new): bool|int
    {
        return parent::update($cond, $new); // TODO: Change the autogenerated stub
    }

    public function updateByIndex(array $cond_array, array $new): bool|int
    {
        return parent::updateByIndex($cond_array, $new); // TODO: Change the autogenerated stub
    }

    public function updateByPk(array|int $pk_arr, array $new): bool|int
    {
        $r= parent::updateByPk($pk_arr, $new); // TODO: Change the autogenerated stub
        if($r){
           $cond=[SysUserConst::pk=>$pk_arr];
           $this->reload($cond);
        }
        return $r;
    }

    // hook dao_sys_user_end.php
}
?>